/****************************************************************************\
* @file     BR_Misc.c
* @author   傅帅
* @date     2019/12/25
* @brief    杂毛
*
******************************************************************************
* @note     本文件存放操作系统及模板的一些初始化函数;
            整合的正点原子usart.c delay.c stmflash.c中的部分内容;
            及实现一些通用功能函数;
****************************************************************************/
#include "stdarg.h"	
#include "string.h"	
#include "stm32f4xx.h"

/**
  * @brief  MemCatenate 解析数据格式，进行内存拼接(C标准库为啥没这玩意 -_-!)
  * @param  TargetAddr  : 目标区块起始地址
            Size        : 目标区块大小
            Format      : 格式化字符串
            ...         : 不定长参数
  * @retval 拼接后的总长度(Byte)
  * @note   处理字符串时本函数不会在末尾加0x00
  */
uint8_t BR_cMemCat(uint8_t *pTargetAddr, uint8_t Size, const char *Format, ...)
{
    va_list pA;
    uint8_t *pTmp = pTargetAddr;
	va_start(pA, Format);
    memset(pTargetAddr, 0, Size);        // 清空缓冲区
    while(*Format != '\0')          // 遍历格式化字符串
    {
        if(*Format != '%')              // 非格式化情况
        {
            memcpy(pTmp++, Format, 1);
        }else                           // 格式化情况
        {
            switch(*++Format)               // 判断是何种情况
            {
                case 'c':       // 8字节 
                {
                    char tmp = (char)va_arg(pA, int);
                    memcpy(pTmp++, &tmp, 1);
                    break;
                }                
                case 'h':       // 16字节 short
                {
                    short tmp = (short)va_arg(pA, int);
                    memcpy(pTmp, &tmp, 2);
                    pTmp += 2;
                    break;                
                }
                case 'f':       // 32字节 float
                {
                    float tmp = (float)va_arg(pA, double);
                    memcpy(pTmp, &tmp, 4);
                    pTmp += 4;
                    break;   
                }  
                case 'd':       // 32字节 int
                {
                    int tmp = (int)va_arg(pA, int);
                    memcpy(pTmp, &tmp, 4);
                    pTmp += 4;
                    break;   
                }                
                case 's':       // 字符串
                {
                    char *p_tmp = va_arg(pA, char*);
                    uint8_t tmp_size = strlen(p_tmp);
                    memcpy(pTmp, p_tmp, tmp_size);
                    pTmp += tmp_size;
                    break;
                }                
            }
        }
        Format++;  // 继续遍历
    }
    return pTmp - pTargetAddr;
}

/** @brief 输入需要计算校验位的字符串，模256校验计算，并将校验结果加至末尾 **/
void BR_vCheckByteCalculateAppend(uint8_t *pStr, uint8_t Len)
{
    uint8_t Sum = 0;
    for(uint8_t i=0;i<Len;i++)Sum+=*pStr++;
    *pStr = (uint8_t)Sum;
}
